<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Manage results from multiple queries</title>
    <link rel="stylesheet" href="https://js.arcgis.com/3.17/dijit/themes/tundra/tundra.css">
    <link rel="stylesheet" href="https://js.arcgis.com/3.17/esri/css/esri.css">
    <style>
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
      #map{ margin: 0; padding: 0; }
      #controls {
        position: absolute;
        height: 80px;
        font-family: arial;
        bottom: 10px;
        margin: 5px;
        padding: 5px;
        z-index: 40;
        background: #fff;
        color: #444;
        width: 440px;
        left: 10px;
        -moz-box-shadow: 0 0 5px #888;
        -webkit-box-shadow: 0 0 5px #888;
        box-shadow: 0 0 5px #888;
      }
      h3 { margin: 0 0 5px 0; border-bottom: 1px solid #444; }
      .label { display: inline-block; width: 140px; }
    </style>

    <script src="https://js.arcgis.com/3.17/"></script>
    <script>
      var app = {};

      require([
        "dojo/parser", "dojo/promise/all", "dojo/_base/connect", 
        "esri/Color", "dojo/_base/array", "dojo/dom",
        "esri/config", "esri/map", "esri/geometry/Extent",
        "esri/symbols/SimpleFillSymbol", "esri/layers/ArcGISDynamicMapServiceLayer",
        "esri/tasks/query", "esri/tasks/QueryTask",
        "dijit/layout/BorderContainer", "dijit/layout/ContentPane",
        "dojo/domReady!"
      ], function(
        parser, all, connect, 
        Color, arrayUtils, dom,
        esriConfig, Map, Extent,
        SimpleFillSymbol, ArcGISDynamicMapServiceLayer,
        Query, QueryTask
      ) {
        // create layout dijits
        parser.parse();
        // specify proxy for request with URL lengths > 2k characters
        esriConfig.defaults.io.proxyUrl = "/proxy/";

        app.map = new Map("map"); 
        var basemap = new ArcGISDynamicMapServiceLayer("https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer");
        app.map.addLayer(basemap);

        // query task and query for parcels
        app.qtParcels = new QueryTask("https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer/2");
        app.qParcels = new Query();
        // query task and query for landuse 
        app.qtBuildings = new QueryTask("https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer/0");
        app.qBuildings = new Query();

        app.qParcels.returnGeometry = app.qBuildings.returnGeometry = true;
        app.qParcels.outFields = app.qBuildings.outFields = ["*"];

        app.map.on("click", executeQueries);

        function executeQueries(e) {
          var parcels, buildings, promises, 
            qGeom, point, pxWidth, padding;

          // create an extent from the mapPoint that was clicked
          // this is used to return features within 3 pixels of the click point
          point = e.mapPoint;
          pxWidth = app.map.extent.getWidth() / app.map.width;
          padding = 3 * pxWidth;
          qGeom = new Extent({
            "xmin": point.x - padding,
            "ymin": point.y - padding,
            "xmax": point.x + padding,
            "ymax": point.y + padding,
            "spatialReference": point.spatialReference
          });

          // use the extent for the query geometry
          app.qParcels.geometry = app.qBuildings.geometry = qGeom;
          
          parcels = app.qtParcels.execute(app.qParcels);
          buildings = app.qtBuildings.execute(app.qBuildings);
          console.log("deferreds: ", parcels, buildings);
          promises = all([parcels, buildings]);
          promises.then(handleQueryResults);
          console.log("created d list");
        }

        function handleQueryResults(results) {
          console.log("queries finished: ", results);
          var parcels, buildings;

          // make sure both queries finished successfully
          if ( ! results[0].hasOwnProperty("features") ) {
            console.log("Parcels query failed.");
          }
          if ( ! results[1].hasOwnProperty("features") ) {
            console.log("Buildings query failed.");
          }

          // results from deferred lists are returned in the order they were created
          // so parcel results are first in the array and buildings results are second
          parcels = results[0].features;
          buildings = results[1].features;

          app.map.graphics.clear();

          // add the results to the map
          arrayUtils.forEach(parcels, function(feat) {
            feat.setSymbol(new SimpleFillSymbol());
            app.map.graphics.add(feat);
          });
          arrayUtils.forEach(buildings, function(feat) {
            feat.setSymbol(
              new SimpleFillSymbol()
                .setColor(new Color([255, 0, 255, 0.5]))
                .setOutline(null)
            );
            app.map.graphics.add(feat);
          });
          dom.byId("results").innerHTML = "Number of parcels:  " +  parcels.length + 
            "<br />Number of buildings:  " + buildings.length;
        }
      });
    </script>
  </head>
  
  <body class="tundra">
    <div data-dojo-type="dijit.layout.BorderContainer" 
         data-dojo-props="design:'headline',gutters:false" 
         style="width: 100%; height: 100%; margin: 0;">
      <div id="map" 
           data-dojo-type="dijit.layout.ContentPane" 
           data-dojo-props="region:'center'">
        
        <div id="controls">
          <h3>Multiple Query Tasks</h3>
          <div id="results">Click the map to query multiple layers.</div>
        </div>

      </div>
    </div>
  </body>
</html>
